//
// Created by tcj on 2021/12/8.
//
#include "util.h"
#include "pthread.h"
#include "sys/types.h"
#include "sys/syscall.h"
#include "stdio.h"
#include <unistd.h>
#include "execinfo.h"

#include "log.h"
#include "fiber.h"

namespace sylar{
    static sylar::Logger::ptr g_logger = SYLAR_LOG_NAME("system");

    pid_t GetThreadId()
    {
//        syscall（）执行一个系统调用
//         得到当前线程id
        return syscall(SYS_gettid);

    }

    u_int32_t GetFirberid(){
        return sylar::Fiber::GetFiberId();
    }

    void Backtrace(std::vector<std::string>& bt,int size,int skip){
        /*
         *在数组中存储当前程序状态的最大返回地址，并返回存储的值的确切数目。
        int backtrace(void **array, int size);

         *从数组中的回溯列表返回一个新的malloc（）内存块中的函数名。
        char **backtrace_symbols(void *const *array, int size);

         *此函数类似于backtrace_symbols（），但它会立即将结果写入文件
        void backtrace_symbols_fd(void *const *array, int size, int fd);
         *
         *
         * */


        void** array = (void**)malloc(sizeof(void*)*size);
        size_t s = ::backtrace(array,size);

        char** strings = backtrace_symbols(array,s);
        if(strings == NULL){
            SYLAR_LOG_ERROR(g_logger)<<"backtrace_synbols_error";
            return;
        }
        for(size_t i=skip;i<s;++i){
            bt.push_back(strings[i]);
        }

        free(strings);
        free(array);
    }

    std::string BacktraceTostring(int size,int skip,const std::string& prefix){
        std::vector<std::string> bt;
        Backtrace(bt,size,skip);
        std::stringstream ss;
        for(size_t i=0;i<bt.size();++i){
            ss<<prefix<<bt[i]<<std::endl;
        }
        return ss.str();
    }


    uint64_t GetCurrentMS(){
        static timeval tv;
        gettimeofday(&tv,NULL);
        return tv.tv_sec*1000ul +tv.tv_usec/1000;
    }
    uint64_t GetCurrentUS(){
        static timeval tv;
        gettimeofday(&tv,NULL);
        return tv.tv_sec*1000*1000ul +tv.tv_usec;

    }
}

